package org.afk.sisy.gui.swing;

import java.awt.*;
import java.awt.event.*;
import java.nio.file.*;

import javax.swing.*;

import net.miginfocom.swing.*;

import org.afk.sisy.*;

public class NewJobGuiComponents
{
	private final PreferencesWrapper preferences;
	private final JDialog mainFrame;
	private final SisyGuiApp gui;
	private final Icons icons;
	private final SisyJob job;
	private JCheckBox scanSecondary;
	private JComboBox<UnmatchedOption> secondaryOrphanOption;
	private JTextField dbNameField;
	private String dbDIr;
	private JTextField primaryPathField;
	private JTextField secondaryPathField;
	private JComboBox<UnmatchedOption> primaryOrphanOption;
	private JComboBox<MatchOption> matchedFiles;
	private JComboBox<CompareOption> compareMethod;
	private JComboBox<SyncOption> syncMethod;
	private JComboBox<AtticOption> atticMode;
	private JButton atticSelector;
	private JTextField atticPath;

	public NewJobGuiComponents(final PreferencesWrapper preferences, final SisyGuiApp guiComponents)
	{
		super();
		this.preferences = preferences;
		this.gui = guiComponents;
		this.icons = this.gui.getIcons();
		this.job = new SisyJob();
		mainFrame = new JDialog(guiComponents.getMainFrame());
		initMainFrame();
	}

	private void addAttic()
	{
		this.mainFrame.add(new JLabel("Attic "), "span, wrap");

		atticMode = new JComboBox<AtticOption>();
		atticMode.setModel(createAtticModel());
		this.mainFrame.add(new JLabel("Attic mode"), "");
		this.mainFrame.add(atticMode, "growx, wrap");

		atticSelector = createStorageSelector();
		atticPath = new JTextField();
		this.mainFrame.add(new JLabel("Attic path"), "");
		this.mainFrame.add(atticPath, "growx");
		this.mainFrame.add(atticSelector, "wrap");
	}

	private ComboBoxModel<AtticOption> createAtticModel()
	{
		return new DefaultComboBoxModel<>(AtticOption.values());
	}

	private void addComparison()
	{
		this.mainFrame.add(new JLabel("Compare "), "span, wrap");

		primaryOrphanOption = new JComboBox<UnmatchedOption>();
		primaryOrphanOption.setModel(createOrphanModel());
		this.mainFrame.add(new JLabel("Primary orphans"), "");
		this.mainFrame.add(primaryOrphanOption, "growx, wrap");

		this.scanSecondary = new JCheckBox("Scan Secondary");
		this.scanSecondary.setSelected(this.job.isScanSecondaryDir());
		this.mainFrame.add(this.scanSecondary, "wrap");

		this.secondaryOrphanOption = new JComboBox<UnmatchedOption>();
		this.secondaryOrphanOption.setModel(createOrphanModel());
		this.mainFrame.add(new JLabel("Secondary orphans"), "");
		this.mainFrame.add(this.secondaryOrphanOption, "growx, wrap");

		matchedFiles = new JComboBox<MatchOption>();
		matchedFiles.setModel(createMatchedModel());
		this.mainFrame.add(new JLabel("Matched files"), "");
		this.mainFrame.add(matchedFiles, "growx, wrap");

		compareMethod = new JComboBox<CompareOption>();
		compareMethod.setModel(createCompareModel());
		this.mainFrame.add(new JLabel("Compare method"), "");
		this.mainFrame.add(compareMethod, "growx, wrap");

	}

	private ComboBoxModel<CompareOption> createCompareModel()
	{
		return new DefaultComboBoxModel<>(CompareOption.values());
	}

	private ComboBoxModel<MatchOption> createMatchedModel()
	{
		return new DefaultComboBoxModel<>(MatchOption.values());
	}

	private void addDbName()
	{
		final JLabel name = new JLabel("Name:");
		this.dbNameField = new JTextField();

		this.mainFrame.add(name, "");
		this.mainFrame.add(this.dbNameField, "growx, wrap");
	}

	private void addOkCancel()
	{
		final JButton ok = new JButton("OK");
		final JButton cancel = new JButton("Cancel");

		this.mainFrame.add(cancel, "span, tag cancel,  split");
		this.mainFrame.add(ok, "tag ok");
	}

	private void addPaths()
	{
		final JLabel paths = new JLabel("Paths");
		this.mainFrame.add(paths, "span, wrap");

		final JLabel primary = new JLabel("Primary:");
		this.primaryPathField = new JTextField();
		final JButton primarySelector = createSourceSelector();

		final JLabel secondary = new JLabel("Secondary:");
		this.secondaryPathField = new JTextField();
		final JButton secondarySelector = createDestinationSelector();

		this.mainFrame.add(primary, "");
		this.mainFrame.add(this.primaryPathField, "growx");
		this.mainFrame.add(primarySelector, "wrap");

		this.mainFrame.add(secondary, "");
		this.mainFrame.add(this.secondaryPathField, "growx");
		this.mainFrame.add(secondarySelector, "wrap");
	}

	private void addSync()
	{
		this.mainFrame.add(new JLabel("Sync "), "span, wrap");

		syncMethod = new JComboBox<SyncOption>();
		syncMethod.setModel(createSyncModel());
		this.mainFrame.add(new JLabel("Sync method"), "");
		this.mainFrame.add(syncMethod, "growx, wrap");

	}

	private ComboBoxModel<SyncOption> createSyncModel()
	{
		return new DefaultComboBoxModel<>(SyncOption.values());
	}

	private void cancel()
	{
		// TODO Auto-generated method stub

	}

	private JButton createDestinationSelector()
	{
		final JButton jButton = new JButton(this.icons.getOpenIcon());
		jButton.setBorder(BorderFactory.createEtchedBorder());
		return jButton;
	}

	private ComboBoxModel<UnmatchedOption> createOrphanModel()
	{
		return new DefaultComboBoxModel<>(UnmatchedOption.values());
	}

	private JButton createSourceSelector()
	{
		final JButton jButton = new JButton(this.icons.getOpenIcon());
		jButton.setBorder(BorderFactory.createEtchedBorder());
		return jButton;
	}

	private JButton createStorageSelector()
	{
		final JButton jButton = new JButton(this.icons.getOpenIcon());
		jButton.setBorder(BorderFactory.createEtchedBorder());
		return jButton;
	}

	private void initMainFrame()
	{
		this.mainFrame.setTitle("Create a new Job");
		final int mainFrameX = this.preferences.getNewJobFrameX();
		final int mainFrameY = this.preferences.getNewJobFrameY();
		final int mainFrameWidth = this.preferences.getNewJobFrameWidth();
		final int mainFrameHeight = this.preferences.getNewJobFrameHeight();
		this.mainFrame.setBounds(mainFrameX, mainFrameY, mainFrameWidth, mainFrameHeight);
		//		mainFrame.setResizable(false);

		this.mainFrame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
		this.mainFrame.setIconImage(this.icons.getFrameIcon().getImage());
		this.mainFrame.setLayout(new MigLayout("", // Layout Constraints
				"[][grow][]", // Column constraints
				"[][shrink 0]")); // Row constraints

		addDbName();
		addPaths();
		addComparison();
		addSync();
		addAttic();
		addOkCancel();

		updateGui();

		// ******************************************************************
		// *  Name:[                                       ]                *
		// *  From:[                                       ][Folder]        *
		// *    To:[                                       ][Folder]        *
		// *[x]Storage:[                                   ][Folder]        *
		// *[x]clean                                                        *
		// *[x]thorough                                                     *
		// *[x]low bandwidth                                [OK]   [CANCEL] *
		// ******************************************************************
		this.mainFrame.addWindowListener(new WindowAdapter()
		{
			@Override
			public void windowClosing(final WindowEvent e)
			{
				save();
				cancel();
				NewJobGuiComponents.this.mainFrame.pack();
				NewJobGuiComponents.this.mainFrame.setVisible(false);
			}
		});

	}

	private void save()
	{

	}

	private void updateJobDatabaseName()
	{
		if (this.dbNameField.getText() != null)
			this.job.setDataBase(Paths.get(this.dbDIr, this.dbNameField.getText()));
		else
			this.job.setDataBase(null);
	}

	private void updateGui()
	{
		updateGuiDatabaseName();
		updateGuiPrimaryPath();
		updateGuiSecondaryPath();
		updateGuiPrimaryOrphans();
		updateGuiSecondaryOrphans();
		updateGuiMatchedFiles();
		updateGuiCompareMethod();
		updateGuiSyncMethod();
		updateGuiAttic();

	}

	private void updateGuiAttic()
	{
		final AtticOption atticOption = job.getAtticOption();
		atticMode.setSelectedItem(atticOption);
		final boolean enableDir = atticOption == AtticOption.MOVE;
		atticPath.setEnabled(enableDir);
		atticSelector.setEnabled(enableDir);
		if (job.getAtticDir() != null)
			atticPath.setText(job.getAtticDir().toString());
		else
			atticPath.setText(null);

		if (!enableDir || atticPath.getText() != null)
			this.atticPath.setBackground(UIManager.getColor("TextField.background"));
		else
			this.atticPath.setBackground(Color.orange);
	}

	private void updateGuiSyncMethod()
	{
		syncMethod.setSelectedItem(job.getSyncOption());
	}

	private void updateGuiCompareMethod()
	{
		compareMethod.setEnabled(job.getMatchOption() == MatchOption.COMPARE);
		compareMethod.setSelectedItem(job.getCompareOption());

	}

	private void updateGuiMatchedFiles()
	{
		this.matchedFiles.setSelectedItem(job.getMatchOption());

	}

	private void updateGuiPrimaryOrphans()
	{
		this.primaryOrphanOption.setSelectedItem(job.getUnmatchedPrimaryOption());

	}

	private void updateGuiSecondaryOrphans()
	{
		final boolean scan = this.job.isScanSecondaryDir();
		this.scanSecondary.setSelected(scan);
		this.secondaryOrphanOption.setEnabled(scan);
		this.secondaryOrphanOption.setSelectedItem(job.getUnmatchedSecondaryOption());
	}

	private void updateGuiPrimaryPath()
	{
		if (this.job.getPrimaryDir() != null)
		{
			this.primaryPathField.setText(job.getPrimaryDir().toString());
			this.primaryPathField.setBackground(UIManager.getColor("TextField.background"));
		}
		else
		{
			this.primaryPathField.setText(null);
			this.primaryPathField.setBackground(Color.orange);
		}
	}

	private void updateGuiSecondaryPath()
	{
		if (this.job.getPrimaryDir() != null)
		{
			this.secondaryPathField.setText(job.getSecondaryDir().toString());
			this.secondaryPathField.setBackground(UIManager.getColor("TextField.background"));
		}
		else
		{
			this.secondaryPathField.setText(null);
			this.secondaryPathField.setBackground(Color.orange);
		}
	}

	private void updateGuiDatabaseName()
	{
		if (this.job.getDataBase() != null)
		{
			this.dbNameField.setText(job.getDataBase().getFileName().toString());
			this.dbNameField.setBackground(UIManager.getColor("TextField.background"));
		}
		else
		{
			this.dbNameField.setText(null);
			this.dbNameField.setBackground(Color.orange);
		}
	}

	private void updateJobPrimaryDir()
	{
		if (this.primaryPathField.getText() != null)
			this.job.setPrimaryDir(Paths.get(this.primaryPathField.getText()));
		else
			this.job.setPrimaryDir(null);
	}

	private void updateJobSecondaryDir()
	{
		if (this.secondaryPathField.getText() != null)
			this.job.setSecondaryDir(Paths.get(this.secondaryPathField.getText()));
		else
			this.job.setSecondaryDir(null);
	}

	private void updateSisyJob()
	{
		updateJobDatabaseName();
		this.job.setScanSecondaryDir(this.scanSecondary.isSelected());
		updateJobPrimaryDir();
		updateJobSecondaryDir();
	}

	public void showJobDialog()
	{
		this.mainFrame.setVisible(true);
	}

}
